package com.zhaolixiang.camera01

import android.content.Context
import android.content.pm.PackageManager
import android.hardware.Camera
import android.util.Log
import android.content.ContentValues.TAG
import android.graphics.Point
import android.graphics.Rect
import android.view.WindowManager
import android.opengl.ETC1.getHeight
import android.opengl.ETC1.getWidth
import android.graphics.Bitmap
import android.graphics.Matrix


/**
 * Created by Administrator on 2017/12/27.
 */
class CameraUtils {
    //默认宽高
    val DEFAULT_WIDTH=1920;
    val DEFAULT_HEIGHT=1080

    //检查是否有可用的拍照设备
    public fun checkCameraHardware(context:Context):Boolean{
        return context.packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA)
    }
    //获取相机相关属性
    public fun getCameraInfo(cameraId:Int): Camera.CameraInfo{
        val cameraInfo=Camera.CameraInfo()
        Camera.getCameraInfo(cameraId,cameraInfo)
        return cameraInfo
    }
    //检测相机是否有指定属性，若有，则设置
    public fun setParameters(camera:Camera,mode:String){
        val parameters=camera.parameters
        when(mode){
            Camera.Parameters.FOCUS_MODE_AUTO->{
                //设置是否可以自动对焦
                val focudModsList=parameters.getSupportedFocusModes()
                if(focudModsList.contains(Camera.Parameters.FOCUS_MODE_AUTO)){
                    //可以自动对焦
                    parameters.focusMode=mode
                    camera.parameters=parameters
                    Log.e("设置属性","可以自动对焦")
                }
            }
        }
    }

    fun getResolution(mCamera:Camera): Camera.Size {
        val params = mCamera.getParameters()
        return params.getPreviewSize()
    }

    // 旋90度
    //参数说明：
     //data 是摄像头捕获数据转灰度后的数据，因为摄像头捕获数据是YUV格式，这样的格式不能直接用该方法旋转否则会出现错误
    //width：相机使用像素对应的宽度
    //height: 相机使用像素对应的高度
    fun getRotation_90(data: ByteArray, width: Int, height: Int) {
        val len = data.size
        if (len != width * height) {
            return
        }
        var rotation: ByteArray? = ByteArray(len)
        var index = 0
        for (i in 0 until width) {
            for (j in height - 1 downTo 0) {
                rotation!![index++] = data[j * width + i]
            }
        }
        for (i in 0 until len) {
            data[i] = rotation!![i]
        }
        rotation = null
    }
    //b：将摄像头捕获的图像信息转转化为像素数组之后生成bitmap 相关转化方法见下文
    //degrees： 将当前图像旋转的角度（该角度值同样是当前屏幕状态下的相机角度）
    fun rotateBitmap(b: Bitmap?, degrees: Float): Bitmap? {
        var b = b
        if (degrees != 0f && b != null) {
            val m = Matrix()
            m.setRotate(degrees, b.width.toFloat() / 2, b.height.toFloat() / 2)
            try {
                val b2 = Bitmap.createBitmap(b, 0, 0, b.width, b.height, m, true)
                if (b != b2) {
                    b.recycle()
                    b = b2
                }
            } catch (ex: OutOfMemoryError) {
                return b
            }

        }
        return b
    }

    // 旋180度
    fun getRotation_180(data: ByteArray, width: Int, height: Int) {
        val len = data.size
        if (len != width * height) {
            return
        }
        for (i in 0 until len / 2) {
            val temp = data[i]
            data[i] = data[len - 1 - i]
            data[len - 1 - i] = temp
        }
    }

    // 旋270度
    fun getRotation_270(data: ByteArray, width: Int, height: Int) {
        val len = data.size
        if (len != width * height) {
            return
        }
        var rotation: ByteArray? = ByteArray(len)
        var index = 0
        for (j in width - 1 downTo 0) {
            for (i in 0 until height) {
                rotation!![index++] = data[i * width + j]
            }
        }
        for (i in 0 until len) {
            data[i] = rotation!![i]
        }
        rotation = null
    }

    //拍照图片分辨率选择
    //在硬件支持的拍照图片分辨率列表中，拍照图片分辨率选择逻辑：
    //有1920*1080则选之
    //选择大于屏幕分辨率且图片比例为16:9的
    //选择图片分辨率尽可能大且图片比例为16:9的
    public fun findBestPictureSizeValue(camera: Camera,context: Context): Point {
        val screenResolution: Point=getScreenSize(context)
        val sizeList = camera.getParameters().getSupportedPictureSizes()
        val tempList = ArrayList<Camera.Size>()
        for (i in sizeList.indices) {
            // 如果有符合的分辨率，则直接返回
            if (sizeList[i].width == DEFAULT_WIDTH && sizeList[i].height == DEFAULT_HEIGHT) {
                Log.d(TAG, "get default picture size!!!")
                return Point(DEFAULT_WIDTH, DEFAULT_HEIGHT)
            }
            if (sizeList[i].width >= screenResolution.x && sizeList[i].height >= screenResolution.y) {
                tempList.add(sizeList[i])
            }
        }

        var bestX = 0
        var bestY = 0
        var diff = Integer.MAX_VALUE
        if (tempList != null && tempList.size > 0) {
            for (i in tempList.indices) {
                val newDiff = Math.abs(tempList.get(i).width - screenResolution.x) + Math.abs(tempList.get(i).height - screenResolution.y)
                val ratio = tempList.get(i).height.toFloat() / tempList.get(i).width
                Log.d(TAG, "ratio = " + ratio)
                if (newDiff < diff && ratio.toDouble() != 0.75) {  // 确保图片是16：9的
                    bestX = tempList.get(i).width
                    bestY = tempList.get(i).height
                    diff = newDiff
                }
            }
        }

        return if (bestX > 0 && bestY > 0) {
            Point(bestX, bestY)
        } else {
            Point(DEFAULT_WIDTH, DEFAULT_HEIGHT)
        }
    }

    //预览图片分辨率选择
    //预览图片的分辨率选择逻辑是：有1920*1080则选之，否则选硬件支持的最大的分辨率，且满足图片比例为16：9
    public fun findBestPreviewSizeValue(camera: Camera, context: Context): Point? {
        val screenResolution: Point=getScreenSize(context)
        val sizeList = camera.getParameters().getSupportedPreviewSizes()
        var bestX = 0
        var bestY = 0
        var size = 0
        for (i in sizeList.indices) {
            // 如果有符合的分辨率，则直接返回
            if (sizeList[i].width == DEFAULT_WIDTH && sizeList[i].height == DEFAULT_HEIGHT) {
                Log.d(TAG, "get default preview size!!!")
                return Point(DEFAULT_WIDTH, DEFAULT_HEIGHT)
            }

            val newX = sizeList[i].width
            val newY = sizeList[i].height
            val newSize = Math.abs(newX * newX) + Math.abs(newY * newY)
            val ratio = newY.toFloat() / newX.toFloat()
            Log.d(TAG, newX.toString() + ":" + newY + ":" + ratio)
            if (newSize >= size && ratio.toDouble() != 0.75) {  // 确保图片是16：9的
                bestX = newX
                bestY = newY
                size = newSize
            } else if (newSize < size) {
                continue
            }
        }

        return if (bestX > 0 && bestY > 0) {
            Point(bestX, bestY)
        } else null
    }

    //获取屏幕大小
    fun getScreenSize(context: Context): Point {
        val wm = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
        return Point(wm.defaultDisplay.width, wm.defaultDisplay.height)
    }
    //剪切摄像头捕获图片
    //与前面对应也有两个方法进行图片剪切
   // 方法一：直接对像素操作
    fun getCutMatrix(camera: Camera,data: ByteArray, mFramingRectInPreview: Rect?): ByteArray? {

        val cameraResolution =camera.parameters.pictureSize
        val pWidth = cameraResolution.width
        val width = mFramingRectInPreview!!.width()
        val height = mFramingRectInPreview!!.height()
        var inputOffset = mFramingRectInPreview!!.top * pWidth + mFramingRectInPreview!!.left
        val area = width * height
        val matrix = ByteArray(area)
        for (y in 0 until height) {
            val outPutOffset = y * width
            System.arraycopy(data, inputOffset, matrix, outPutOffset, width)
            inputOffset += pWidth
        }
        return matrix
    }
}